home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 July: Mac OS SDK / Dev.CD Jul 97 SDK2.toast / Development Kits (Disc 2) / Thread Manager / Thread Manager 2.1.1d1+ / ThreadedSort / Sprocket / Lib / SprocketMain.cp < prev    next >
Encoding:
Text File  |  1995-04-28  |  16.3 KB  |  640 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        SprocketMain.cp
  3.  
  4.     Contains:    The “guts” of a Macintosh application.
  5.  
  6.     Written by: Dave Falkenburg and many other SmartFriends™
  7.  
  8.     Copyright:    © 1993-94 by Dave Falkenburg, all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.      
  12.         <11>    11/16/94    DRF        Added an explicit #include <Traps.h> for latest universal
  13.                                     headers. Also killed off a CFront warning.
  14.         <10>    11/12/94    DRF        Revised QuickDrawGX initialization based on changes made by Jon
  15.                                     Summer. We now use a 'gasz' resource to setup the size of the
  16.                                     graphics heap. Also we are now always TSM aware, not just when
  17.                                     TSMTE is around.
  18.          <9>     11/8/94    DRF        Rolled in LDR’s TSM fixes. Add fonts to the Fonts menu if it
  19.                                     exists. Also, stop openning up the preferences file here.
  20.          <8>     9/27/94    DRF         AppLib.h is now Sprocket.h, also fixed scrap coercion routines
  21.                                      and eliminated HandleUpdate.
  22.          <7>      9/9/94    DRF        Reordered headers and removed redundant #includes.
  23.                                     Conditionalized AOCE support. Also made changes to
  24.                                     TSMEventWrapper to be more like the code in InlineInputSample.
  25.          <6>      9/8/94    DRF        Add HiliteMenu(0) calls after calls to menu handling code
  26.                                     because TSMMenuSelect doesn’t do it. Also reorganized some GX
  27.                                     stuff: allocate and release a graphicsclient (Cam claims this
  28.                                     works on his machine), and turn on all the graphics errors and
  29.                                     notices if qDebug is set.
  30.          <5>      9/7/94    DRF        Rearrange YieldToAnyThread calls to make quitting faster.
  31.          <4>      9/4/94    DRF        Rearrange local variables in HandleMouseDown.
  32.          <3>      9/1/94    DRF        Stop including "MailableWindow.h" here.
  33.          <2>      9/1/94    DRF        More fixes for inline input, but we’re not really done yet.
  34.  */
  35.  
  36. #include "Sprocket.h"
  37.  
  38. #include <limits.h>        //    For LONG_MAX
  39.  
  40. #include <Fonts.h>
  41. #include <Desk.h>
  42. #include <GestaltEqu.h>
  43. #include <DiskInit.h>
  44. #include <Threads.h>
  45. #include <FragLoad.h>    //    for kUnresolvedSymbolAddress
  46. #include <Traps.h>
  47.  
  48. #if    qInlineInputAware
  49. #include <TextServices.h>
  50. #include <TSMTE.h>
  51. #endif
  52.  
  53. #if    qUseQuickDrawGX
  54. #include <graphics macintosh.h>
  55. #include <graphics routines.h>
  56. #include <graphics libraries.h>
  57. #include <PrintingManager.h>
  58. #endif
  59.  
  60. #include "StandardMenus.h"
  61. #include "Window.h"
  62. #include "SplashWindow.h"
  63. #include "AppleEventHandling.h"
  64.  
  65.  
  66. //    Function Prototypes
  67.  
  68. void    main(void);
  69. void    MainEventLoop(void);
  70.  
  71. void    HandleMouseDown(TWindow * topWindowObj, EventRecord * anEvent);
  72. void    HandleClose(WindowPtr aWindow);
  73.  
  74.  
  75. //    Globals
  76.  
  77. Boolean                gDone = false;
  78. Boolean                gMenuBarNeedsUpdate = true;
  79.  
  80. Boolean                gHasColorQuickdraw = false;
  81. Boolean                gHasThreadManager = false;
  82. Boolean                gHasDragManager = false;
  83. Boolean                gHasAppleScript = false;
  84. Boolean                gHasDisplayManager = false;
  85.  
  86. GrafPtr                gWindowManagerPort;
  87. Rect                gDeskRectangle;
  88. RgnHandle            gMouseRegion = nil;
  89.  
  90. short                gPreferencesRsrcRefNum;
  91.  
  92. #if    qAOCEAware
  93. Boolean                gHasAOCE = false;
  94. #endif
  95.  
  96. #if    qInlineInputAware
  97. Boolean                gHasTextServices = false;
  98. Boolean                gHasTSMTE = false;
  99.  
  100. Boolean                TSMEventWrapperForKotoeri(EventRecord *anEvent);
  101.  
  102. #endif
  103.  
  104. #if    qUseQuickDrawGX
  105. Boolean                gHasQuickDrawGX = false;
  106. long                gQuickDrawGXVersion = 0;
  107. long                gQuickDrawGXPrintingVersion = 0;
  108. gxGraphicsClient    gQuickDrawGXClient;
  109. #endif
  110.  
  111.  
  112. //    Values that can be adjusted by other application code to change
  113. //    the behavior of the MainEventLoop.
  114. //
  115. //    Rules of thumb:
  116. //
  117. //        Increase gXXXRunQuantum (and decrease gXXXSleepQuantum) when:
  118. //            The application has many threads running that need time
  119. //
  120. //        Decrease gXXXRunQuantum when:
  121. //            Sending AppleEvents to other applications
  122. //            Launching other applications
  123. //            Running in the background
  124.  
  125. unsigned long    gForegroundRunQuantum = 0;
  126. unsigned long    gForegroundSleepQuantum = GetCaretTime();
  127. unsigned long    gBackgroundRunQuantum = 0;
  128. unsigned long    gBackgroundSleepQuantum = LONG_MAX;
  129.  
  130.  
  131. //    Globals used to “tune” the performance of MainEventLoop
  132. //    (assume we’ll be starting in the foreground)
  133.  
  134. static    unsigned long    gRunQuantum = gForegroundRunQuantum;
  135. static    unsigned long    gSleepQuantum = gForegroundSleepQuantum;
  136.  
  137. #ifdef    powerc
  138. #ifndef    __MWERKS__
  139. QDGlobals    qd;
  140. #endif
  141. #endif
  142.  
  143. void
  144. main(void)
  145.     {
  146.     long        feature;
  147.  
  148.     MaxApplZone();
  149.     MoreMasters();
  150.     MoreMasters();
  151.     MoreMasters();
  152.     MoreMasters();
  153.  
  154.     InitGraf(&qd.thePort);    
  155.     InitFonts();
  156.     InitWindows();
  157.     InitMenus();
  158.     TEInit();
  159.     InitDialogs(nil);
  160.  
  161.  
  162.     if (GetToolTrapAddress(_Unimplemented) == GetOSTrapAddress(_Gestalt))
  163.         FatalErrorAlert(kCoreErrorStrings,kUnsupportedSystemSoftware);
  164.  
  165.     if (Gestalt(gestaltQuickdrawFeatures,&feature) == noErr)
  166.         gHasColorQuickdraw = ((feature & (1 << gestaltHasColor)) != 0);
  167.  
  168.     
  169.     TSplashWindow * splashWindow = new TSplashWindow;
  170.  
  171.     //    Check for and Initialize QuickDraw GX early on to avoid heap fragmentation
  172.     
  173. #if    qUseQuickDrawGX
  174.     //    Check for and initialize QuickDrawGX
  175.     if (Gestalt(gestaltGXVersion, &gQuickDrawGXVersion) == noErr)
  176.         {
  177.         if (Gestalt(gestaltGXPrintingMgrVersion, &gQuickDrawGXPrintingVersion) == noErr)
  178.             {
  179. #if defined(__CFM68K__) || defined(__powerc) 
  180.             if ((Ptr) GXEnterGraphics != kUnresolvedSymbolAddress)
  181. #endif
  182.             gHasQuickDrawGX = true;
  183.             }
  184.         }
  185.  
  186.     if (gHasQuickDrawGX)
  187.         {
  188.         // Initialize the graphics and printing environments.
  189.         //    For additional details see "IM: QD GX Environment & Utilities."
  190.         
  191.         //    We let QuickDraw GX look for a resource  of type 'gasz' with an ID of 0.
  192.         //    GX uses the first long word of that resource as the graphics heap size.
  193.         //    To determine the memory requirements of your graphics client heap see:
  194.         //    “IM: QD GX Environment & Utilities pp2-8,2-9”
  195.         
  196.         //    NOTE:    If your application does not provide this resource,
  197.         //            QuickDraw GX version 1.0 uses a default size of 600 KB.
  198.  
  199.         gQuickDrawGXClient = GXNewGraphicsClient(nil, kUseGraphicsSizeResource, kAllowGXToExtendGraphicsHeap);
  200.         if (gQuickDrawGXClient)
  201.             {
  202.             //    NOTE:    GXNewGraphicsClient() does not allocate memory to the heap
  203.             //            until GXEnterGraphics()    is called, so go ahead and call it now
  204.             //            while we have a chance to deal with things nicely.
  205.             //
  206.             // NOTE:    GXEnterGraphics() should only fail if there is not enough memory. 
  207.             
  208.             GXEnterGraphics();
  209.  
  210.             if (GXGetGraphicsError(nil) == noErr)
  211.                 {
  212. #if    qUseQuickDrawGXDebugging
  213.                 // If qUseQuickDrawGXDebugging = TRUE, enable on GX Validation and graphics library errors & notices.
  214.  
  215.                 //    NOTES from Jon Summers:
  216.                 //    As you increase the amount of validation, drawing speed will SLOW
  217.                 //    down due to all of the internal checking. Also, if you play with
  218.                 //    settings enough validation seems to become inconsistent
  219.  
  220.                 GXSetValidation(    //    gxInternalValidation    |
  221.                                     //    gxAllObjectValidation    |
  222.                                     //    gxApHeapValidation        |
  223.                                         gxPublicValidation);        // check parameters to public routines
  224.  
  225.                 //    This functionality will only work with the "debugging" version of QuickDraw GX.
  226.                 //    If you don't have the debugging version installed, these functions will not work. 
  227.  
  228.                 SetGraphicsLibraryErrors();
  229.                 SetGraphicsLibraryNotices();    
  230. #endif
  231.                 if (GXInitPrinting() != noErr)        // See IM: QuickDraw GX Printing
  232.                     {
  233.                     //    We couldn’t initialize printing, so clean up pretend GX isn’t around
  234.                     //    ••• For safety’s sake, we’ll probably want to bail here.
  235.                     
  236.                     if (gQuickDrawGXClient)
  237.                         GXDisposeGraphicsClient(gQuickDrawGXClient);
  238.                     gHasQuickDrawGX = false;
  239.                     }
  240.                 }
  241.             }
  242.         }
  243.  
  244.     if (gQuickDrawGXClient)
  245.         InitCommonColors();        // Initialize the CommonColors Library.
  246. #if    qRequireQuickDrawGX
  247.     else
  248.         FatalErrorAlert(kCoreErrorStrings, kNeedsQuickdrawGX);
  249. #endif    //    qRequireQuickDrawGX
  250. #endif    //    qUseQuickDrawGX
  251.  
  252.  
  253.     if ((Gestalt(gestaltAppleEventsAttr,&feature) == noErr) &&
  254.         (feature & (1 << gestaltAppleEventsPresent)))
  255.         {
  256.         //    Figure out if we need to do AppleEvent recording
  257.         gHasAppleScript = ((feature & (1 << gestaltScriptingSupport)) != 0);
  258.         }
  259.     else
  260.         FatalErrorAlert(kCoreErrorStrings,kUnsupportedSystemSoftware);
  261.  
  262. #if    qInlineInputAware
  263.     if ((Gestalt(gestaltTSMgrVersion,&feature) == noErr) && (feature >= 1))
  264.         {
  265.         gHasTextServices = true;
  266.         if (Gestalt(gestaltTSMTEAttr, &feature) == noErr)
  267.             gHasTSMTE = (feature & (1 << gestaltTSMTEPresent));
  268.  
  269.         if (InitTSMAwareApplication() != noErr)
  270.             {
  271.             gHasTextServices = false;
  272.             gHasTSMTE = false;
  273.             }
  274.         }
  275.  
  276. #endif
  277.  
  278.     if (Gestalt(gestaltThreadMgrAttr,&feature) == noErr)
  279.         {
  280. #if defined(__CFM68K__) || defined(__powerc)
  281.         //    If running on a PowerPC, make sure that we not only have the
  282.         //    68K Thread Manager, but also the PowerPC shared library, too.
  283.         //    Because of the wonders of weak linking and out of memory errors
  284.         //    we need to also check to make sure that an entrypoint in the library
  285.         //    is there, too. 
  286.         if ((Ptr) NewThread != kUnresolvedSymbolAddress)
  287.             gHasThreadManager = ((feature & ((1 << gestaltThreadMgrPresent) | (1 << gestaltThreadsLibraryPresent))) != 0);
  288. #else
  289.         gHasThreadManager = ((feature & (1 << gestaltThreadMgrPresent)) != 0);
  290. #endif
  291.         }
  292.  
  293. #if    qRequireThreadManager
  294.     if (gHasThreadManager == false)
  295.         FatalErrorAlert(kCoreErrorStrings, kNeedsThreadManager);
  296. #endif
  297.  
  298.     //    Check for and install Drag Manager callbacks
  299.     if (Gestalt(gestaltDragMgrAttr,&feature) == noErr)
  300.         {
  301. #if defined(__CFM68K__) || defined(__powerc)
  302.         //    If running on a PowerPC, make sure that we not only have the
  303.         //    68K Drag Manager, but also the PowerPC shared library, too.
  304.         if ((Ptr) NewDrag != kUnresolvedSymbolAddress)
  305.             gHasDragManager = ((feature & ((1 << gestaltDragMgrPresent) | (1 << gestaltPPCDragLibPresent))) != 0);
  306. #else
  307.         gHasDragManager = ((feature & (1 << gestaltDragMgrPresent)) != 0);
  308. #endif
  309.  
  310.         if (gHasDragManager)
  311.             {
  312.             InstallTrackingHandler( NewDragTrackingHandlerProc( CallWindowDragTrackingHandler ), ( WindowPtr )nil, nil );
  313.             InstallReceiveHandler( NewDragReceiveHandlerProc( CallWindowDragReceiveHandler ), ( WindowPtr )nil, nil );
  314.             }
  315.         }
  316.  
  317.     //    Check for Display Manager
  318.     if (Gestalt(gestaltDisplayMgrAttr,&feature) == noErr)
  319.         gHasDisplayManager = ((feature & (1 << gestaltDisplayMgrPresent)) != 0);
  320.  
  321. #if    qAOCEAware    
  322.     //    Check for and initialize AOCE Standard Mail package if it exists
  323.     if ((Gestalt(gestaltSMPMailerVersion,&feature) == noErr) && (feature != 0))
  324.         {
  325. #if defined(__CFM68K__) || defined(__powerc)
  326.         if ((Ptr) SMPInitMailer != kUnresolvedSymbolAddress)
  327.             gHasAOCE = (SMPInitMailer(kSMPVersion) == noErr);
  328. #else
  329.         gHasAOCE = (SMPInitMailer(kSMPVersion) == noErr);
  330. #endif
  331.         }
  332. #endif
  333.  
  334.     //    Install our AppleEvent Handlers
  335.     InstallAppleEventHandlers();
  336.  
  337.     //    Setup desktop rectangle for dragging windows around            
  338.     GetWMgrPort(&gWindowManagerPort);
  339.     gDeskRectangle = (**GetGrayRgn()).rgnBBox;
  340.  
  341.     //    Get the default menubar
  342.     SetMenuBar(GetNewMBar(rMenuBar));
  343.     AddResMenu(GetMHandle(mApple),'DRVR');
  344.  
  345.     // Add fonts to the font menu if it installed
  346.     if (GetMHandle(mFont))
  347.         AddResMenu(GetMHandle(mFont),'FONT');
  348.     
  349.     if (SetupApplication() == noErr)
  350.         {
  351.         delete    splashWindow;    //    get rid of the splash screen
  352.         MainEventLoop();
  353.         TearDownApplication();
  354.         }
  355.  
  356. #if    qInlineInputAware
  357.     if (gHasTextServices)
  358.         (void) CloseTSMAwareApplication();
  359. #endif
  360.         
  361. #if    qUseQuickDrawGX
  362.     //    Tear down QuickDrawGX
  363.     if (gHasQuickDrawGX && gQuickDrawGXClient)
  364.         {
  365.         DisposeCommonColors();
  366.         GXExitPrinting();        // Close the new printing mgr. 
  367.         GXExitGraphics();        // Deallocate all of the default structures
  368.         GXDisposeGraphicsClient(gQuickDrawGXClient);    
  369.         }
  370. #endif
  371.     }
  372.  
  373.  
  374. void
  375. MainEventLoop(void)
  376.     {
  377.     EventRecord        anEvent;
  378.     unsigned long    nextTimeToCheckForEvents = 0;
  379.     
  380.     while (!gDone)
  381.         {
  382.         if (gMenuBarNeedsUpdate)
  383.             {
  384.             gMenuBarNeedsUpdate = false;
  385.             DrawMenuBar();
  386.             }
  387.  
  388.         if (gHasThreadManager)
  389.             YieldToAnyThread();
  390.  
  391.         if ((gRunQuantum == 0) ||
  392.             (TickCount() > nextTimeToCheckForEvents))
  393.             {
  394.             nextTimeToCheckForEvents = TickCount() + gRunQuantum;
  395.             
  396.             (void) WaitNextEvent(everyEvent,&anEvent,gSleepQuantum,gMouseRegion);
  397.                         
  398. #if    qInlineInputAware
  399.             if (gHasTextServices && TSMEventWrapperForKotoeri(&anEvent))
  400.                 {
  401.                 }
  402.             else
  403. #endif
  404.                 HandleEvent(&anEvent);
  405.             }
  406.         }
  407.     }
  408.  
  409. #if    qInlineInputAware
  410.  
  411. Boolean
  412. TSMEventWrapperForKotoeri(EventRecord *anEvent)
  413.     {
  414.     short        oldFont;
  415.     ScriptCode    keyboardScript;
  416.     Boolean        didTSMHandleTheEvent = false;
  417.  
  418.     //    This snippet of code is from TE 27: Inline Input & TextEdit
  419.     //    and is related to working around a bug in Kotoeri, one of the
  420.     //    Japanese Input methods when operating in a mixed script
  421.     //    environment (e.g., Japanese Language Kit)
  422.     
  423.     // make sure we have a port and it's not the Window Manager port
  424.     if (qd.thePort != nil)
  425.         {
  426.         oldFont            = qd.thePort->txFont;
  427.         keyboardScript    = GetScriptManagerVariable(smKeyScript);
  428.  
  429.         if (FontToScript(oldFont) != keyboardScript)
  430.             TextFont(GetScriptVariable(keyboardScript, smScriptAppFond));
  431.         }
  432.  
  433.     didTSMHandleTheEvent = TSMEvent(anEvent);
  434.     
  435.     TextFont(oldFont);        //    restore the font, even though the sample code didn’t
  436.  
  437.     return didTSMHandleTheEvent;
  438.     }
  439.  
  440. #endif    
  441.  
  442.  
  443.  
  444. void
  445. HandleEvent(EventRecord *anEvent)
  446.     {
  447.     TWindow    * wobj;
  448.     
  449.     if (anEvent->what != updateEvt)
  450.         wobj = GetWindowObject(FrontNonFloatingWindow());
  451.     else
  452.         wobj = GetWindowObject((WindowPtr) anEvent->message);
  453.  
  454.     if (wobj != nil)
  455. #if    qInlineInputAware
  456.         // give text services a chance to set the cursor shape
  457.         if (gHasTextServices && SetTSMCursor(anEvent->where))
  458.             ;    // do nothing, TSM did it for me
  459.         else    
  460. #endif
  461.             wobj->AdjustCursor(anEvent);
  462.     
  463.     if ((wobj != nil) && wobj->EventFilter(anEvent))
  464.         return;
  465.         
  466.     else switch (anEvent->what)
  467.         {
  468.         case    nullEvent:
  469.             if (wobj != nil)
  470.                 wobj->Idle(anEvent);
  471.             break;
  472.             
  473.         case    mouseDown:
  474.             HandleMouseDown(wobj,anEvent);
  475.             break;
  476.         
  477.         case    keyDown:
  478.         case    autoKey:
  479.             if (anEvent->modifiers & cmdKey)
  480.                 {
  481.                 long    menuResult = MenuKey((short) anEvent->message & charCodeMask);
  482. #if    qInlineInputAware
  483.                 if (!(gHasTextServices && TSMMenuSelect(menuResult)))
  484. #endif
  485.                     HandleMenu(wobj,menuResult);
  486.                 HiliteMenu(0);
  487.                 }
  488.             else if (wobj != nil)
  489.                 wobj->KeyDown(anEvent);
  490.             break;
  491.             
  492.         case    updateEvt:
  493.             {
  494.             GrafPtr        oldPort;
  495.             WindowPtr    aWindow = (WindowPtr) anEvent->message;    
  496.                 
  497.             GetPort(&oldPort);
  498.             SetPort(aWindow);
  499.             BeginUpdate(aWindow);
  500.             if (wobj != nil)
  501.                 wobj->Draw();
  502.             EndUpdate(aWindow);
  503.             SetPort(oldPort);
  504.             }
  505.             break;
  506.             
  507.         case diskEvt:
  508.             if (anEvent->message >> 16)
  509.                 {
  510.                 static    Point    where = {50,50};
  511.                 (void) DIBadMount(where,anEvent->message);
  512.                 }
  513.             break;
  514.                 
  515.         case    osEvt:
  516.             switch ((anEvent->message & osEvtMessageMask) >> 24)
  517.                 {
  518.                 case    mouseMovedMessage:
  519.                     break;
  520.                     
  521.                 case    suspendResumeMessage:                    
  522.  
  523.                     SuspendResumeWindows((anEvent->message & resumeFlag) != 0);
  524.  
  525.                     if (anEvent->message & resumeFlag)
  526.                         {
  527.                         if (anEvent->message & convertClipboardFlag)
  528.                             ReadLocalClipboardFromScrap();
  529.  
  530.                         gRunQuantum = gForegroundRunQuantum;
  531.                         gSleepQuantum = gForegroundSleepQuantum;
  532.                         }
  533.                     else
  534.                         {
  535.                         if (anEvent->message & convertClipboardFlag)
  536.                             WriteLocalClipboardToScrap();
  537.                         gRunQuantum = gBackgroundRunQuantum;
  538.                         gSleepQuantum = gBackgroundSleepQuantum;
  539.                         }
  540.  
  541.                     break;
  542.                 }
  543.             break;
  544.         
  545.         case    kHighLevelEvent:
  546.             (void) AEProcessAppleEvent(anEvent);
  547.             break;
  548.             
  549.         default:
  550.             break;
  551.         }
  552.     }
  553.  
  554. void
  555. HandleMouseDown(TWindow * topWindowObj,EventRecord *anEvent)
  556.     {
  557.     WindowPtr    aWindow;
  558.     TWindow        *wobj;
  559.     short        partCode;
  560.  
  561.     partCode = FindWindow(anEvent->where,&aWindow);
  562.     wobj = GetWindowObject(aWindow);
  563.     switch(partCode)
  564.         {
  565.         case    inMenuBar:
  566.             long    menuResult = MenuSelect(anEvent->where);
  567. #if    qInlineInputAware
  568.             if (!(gHasTextServices && TSMMenuSelect(menuResult)))
  569. #endif
  570.                 HandleMenu(topWindowObj,menuResult);
  571.             HiliteMenu(0);
  572.             break;
  573.             
  574.         case    inSysWindow:
  575.             SystemClick(anEvent,aWindow);
  576.             break;
  577.             
  578.         case    inContent:
  579.             if (wobj)
  580.                 {
  581.                 GrafPtr    oldPort;
  582.                 
  583.                 GetPort(&oldPort);
  584.                 SetPort(aWindow);
  585.                 GlobalToLocal(&anEvent->where);
  586.                 wobj->Click(anEvent);
  587.                 SetPort(aWindow);
  588.                 }
  589.             break;
  590.             
  591.         case    inDrag:
  592.             if (wobj)
  593.                 wobj->Drag(anEvent->where);
  594.             break;
  595.             
  596.         case    inGrow:
  597.             if (wobj)
  598.                 wobj->Grow(anEvent->where);
  599.             break;
  600.             
  601.         case    inGoAway:
  602.             if (TrackGoAway(aWindow,anEvent->where))
  603.                 HandleClose(aWindow);
  604.             break;
  605.  
  606.         case    inZoomIn:
  607.         case    inZoomOut:
  608.             if (TrackBox(aWindow,anEvent->where,partCode) && (wobj))
  609.                 wobj->Zoom(partCode);
  610.             break;
  611.             
  612.         default:
  613.             break;
  614.         }
  615.     }
  616.     
  617.  
  618. void
  619. HandleClose(WindowPtr aWindow)
  620.     {
  621.     short    windowKind;
  622.     TWindow    *wobj;
  623.     
  624.     if (aWindow)
  625.         {
  626.         windowKind = ((WindowPeek) aWindow)->windowKind;
  627.         if (windowKind < 0)
  628.             {
  629.             CloseDeskAcc(((WindowPeek)aWindow)->windowKind);
  630.             }
  631.         else if ( ((wobj = GetWindowObject(aWindow)) != nil) &&
  632.                     wobj->CanClose() &&
  633.                     wobj->Close() &&
  634.                     wobj->DeleteAfterClose())
  635.             {
  636.             delete wobj;
  637.             }
  638.         }
  639.     }
  640.